#ifndef _MARCHING_H_
#define _MARCHING_H_


#include "vec.h"
#include "modelerdraw.h"
#include <vector>

// hack...
extern void _setupOpenGl();
extern void _dump_current_modelview();
extern void _dump_current_material();

// *** Metaball related stuff *** /
class Marching
{
public:
	Marching(int num_divx, int num_divy, int num_divz);
	~Marching();

	void Prepare();
	void Draw();

	void AddMetaball(float x, float y, float z, float mass = 1.0f);
	void SetMetaThreshold(float thres);
	void SetBallPower(int id, float power);
	void SetBallPosition(int id, Vec3f pos);

private:

	void computeMetaGrid();
	void computeTriangles();
	void AddTriangles(int corners, int x, int y, int z);

	// Sampling 3d array
	vector<vector<vector<bool> > > meta_grid;

	// Triangles we need to render
	vector<int > meta_triangles; // first element is 0, 1, 2, for which array(plane - XY, XZ, YZ) we are talking about, and the next for the index
	
	// Metaball information
	vector<Vec4f> metaballs;

	int NUM_DIVISIONS_X; 
	int NUM_DIVISIONS_Y; 
	int NUM_DIVISIONS_Z; 

	float META_THRESHOLD;

	float* VERTEX_ARRAY_XY;
	float* VERTEX_ARRAY_YZ;
	float* VERTEX_ARRAY_XZ;

	float* VERTEX_NORMALS;
	int* VERTEX_NUM_TRIANGLES;

	int INDEX_START_XY;
	int INDEX_START_YZ;
	int INDEX_START_XZ;

	static const float meta_gridMin[3];
	static const float meta_gridMax[3];

	// lookup table for marching cubes. Contains 3 * N points for N triangles, each successive 3 representing a single triangle
	static const int marching_lookup[256][16]; 
};

#endif